package com.nf.mvc.support;

import com.nf.mvc.support.converter.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class WebTypeConverters {

    private final static Map<Class<?>, WebTypeConverter<?>> CACHED_CONVERTERS = new ConcurrentHashMap<>(32);

    static {
        CACHED_CONVERTERS.put(BigDecimal.class, new BigDecimalTypeConverter());
        CACHED_CONVERTERS.put(Boolean.class, new BooleanTypeConverter());
        CACHED_CONVERTERS.put(Boolean.TYPE, new BooleanTypeConverter());
        CACHED_CONVERTERS.put(Byte.class, new ByteTypeConverter());
        CACHED_CONVERTERS.put(Byte.TYPE, new ByteTypeConverter());
        CACHED_CONVERTERS.put(Character.class, new CharacterTypeConverter());
        CACHED_CONVERTERS.put(Character.TYPE, new CharacterTypeConverter());
        CACHED_CONVERTERS.put(Date.class, new DateTypeConverter());
        CACHED_CONVERTERS.put(Double.class, new DoubleTypeConverter());
        CACHED_CONVERTERS.put(Double.TYPE, new DoubleTypeConverter());
        CACHED_CONVERTERS.put(Float.class, new FloatTypeConverter());
        CACHED_CONVERTERS.put(Float.TYPE, new FloatTypeConverter());
        CACHED_CONVERTERS.put(Integer.class, new IntegerTypeConverter());
        CACHED_CONVERTERS.put(Integer.TYPE, new IntegerTypeConverter());
        CACHED_CONVERTERS.put(LocalDateTime.class, new LocalDateTimeTypeConverter());
        CACHED_CONVERTERS.put(LocalDate.class, new LocalDateTypeConverter());
        CACHED_CONVERTERS.put(LocalTime.class, new LocalTimeTypeConverter());
        CACHED_CONVERTERS.put(Long.class, new LongTypeConverter());
        CACHED_CONVERTERS.put(Long.TYPE, new LongTypeConverter());
        CACHED_CONVERTERS.put(Short.class, new ShortTypeConverter());
        CACHED_CONVERTERS.put(Short.TYPE, new ShortTypeConverter());
        CACHED_CONVERTERS.put(String.class, new StringTypeConverter());
    }

    public static WebTypeConverter<?> getTypeConverter(Class<?> paramType) {
        return CACHED_CONVERTERS.get(paramType);
    }

    public static <T> Object convert(String value, Class<T> valueType) throws Exception {
        WebTypeConverter<?> converter = getTypeConverter(valueType);
        if (converter == null) {
            throw new UnsupportedOperationException("不支持对此类型进行转换操作");
        }
        //表明已经有对应的转换器了
        try {
            return converter.convert(value);
        } catch (Exception e) {
            throw new IllegalArgumentException("无法将数据:[" + value + "]转换为类型:" + valueType.getName());
        }
    }

}
